class LabelDemo {
    constructor() {
        this.scene = null;
        this.camera = null;
        this.renderer = null;
        this.css2DRenderer = null;
        this.css3DRenderer = null;
        this.controls = null;
        this.currentLabelType = 'css2d';
        this.demoObjects = [];
        this.css2dLabels = [];
        this.css3dLabels = [];
        this.spriteLabels = [];
        this.css3dSpriteLabels = [];
        this.animationId = null;
        this.autoRotate = true;
        this.rotationSpeed = 0.01;
        this.showAll = true;
        this.labelVisibility = {
            css2d: true,
            css3d: true,
            css3dsprite: true,
            sprite: true
        };
        
        // 性能监控
        this.performanceMonitor = {
            fps: 0,
            frameCount: 0,
            lastTime: performance.now(),
            renderTime: 0
        };
        
        // 标签类型信息
        this.labelTypes = {
            css2d: {
                name: 'CSS2DRenderer',
                description: '基于DOM的2D标签渲染器，标签始终面向相机，不受3D透视影响',
                features: ['DOM渲染', '2D显示', 'HTML交互', 'CSS样式'],
                advantages: ['完全的HTML/CSS支持', '丰富的交互能力', '易于样式定制'],
                limitations: ['不支持3D透视', '性能相对较低', '层级管理复杂'],
                useCases: ['信息面板', '用户界面', '复杂标签内容']
            },
            css3d: {
                name: 'CSS3DRenderer',
                description: '基于DOM的3D标签渲染器，支持3D变换和透视效果',
                features: ['DOM渲染', '3D透视', 'HTML交互', 'CSS3D变换'],
                advantages: ['支持3D透视', '完整HTML/CSS功能', '立体视觉效果'],
                limitations: ['性能开销大', '复杂场景卡顿', '移动端兼容性'],
                useCases: ['3D界面', '立体标签', '沉浸式体验']
            },
            sprite: {
                name: 'Sprite',
                description: '基于WebGL的纹理标签，高性能渲染，支持3D透视',
                features: ['WebGL渲染', '3D透视', '高性能', '纹理映射'],
                advantages: ['最高性能', '支持大量标签', '3D透视效果'],
                limitations: ['不支持HTML交互', '样式定制受限', '文本渲染复杂'],
                useCases: ['粒子标签', '大量标记', '性能要求高的场景']
            },
            css3dsprite: {
                name: 'CSS3DSprite',
                description: '基于CSS3D的精灵标签，结合DOM元素和3D变换的优势',
                features: ['CSS3D渲染', '精灵特性', 'DOM元素', '3D透视'],
                advantages: ['支持HTML/CSS', '3D透视效果', '始终面向相机', '良好性能'],
                limitations: ['需要CSS3D支持', '复杂场景性能下降', '移动端兼容性'],
                useCases: ['混合渲染', '3D界面元素', '交互式标签']
            }
        };
        
        this.init();
        this.setupEventListeners();
        this.createDemoObjects();
        this.animate();
    }
    
    init() {
        const canvas = document.getElementById('canvas');
        const container = canvas.parentElement;
        
        // 创建场景
        this.scene = new THREE.Scene();
        this.scene.background = new THREE.Color(0x1a1a2e);
        
        // 创建相机
        this.camera = new THREE.PerspectiveCamera(
            75,
            container.clientWidth / container.clientHeight,
            0.1,
            1000
        );
        this.camera.position.set(10, 10, 10);
        
        // 创建WebGL渲染器
        this.renderer = new THREE.WebGLRenderer({ 
            canvas: canvas,
            antialias: true,
            alpha: true
        });
        this.renderer.setSize(container.clientWidth, container.clientHeight);
        this.renderer.shadowMap.enabled = true;
        this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
        
        // 创建CSS2D渲染器
        this.css2DRenderer = new THREE.CSS2DRenderer();
        this.css2DRenderer.setSize(container.clientWidth, container.clientHeight);
        this.css2DRenderer.domElement.style.position = 'absolute';
        this.css2DRenderer.domElement.style.top = '0';
        this.css2DRenderer.domElement.style.pointerEvents = 'none';
        container.appendChild(this.css2DRenderer.domElement);
        
        // 创建CSS3D渲染器
        this.css3DRenderer = new THREE.CSS3DRenderer();
        this.css3DRenderer.setSize(container.clientWidth, container.clientHeight);
        this.css3DRenderer.domElement.style.position = 'absolute';
        this.css3DRenderer.domElement.style.top = '0';
        this.css3DRenderer.domElement.style.pointerEvents = 'none';
        container.appendChild(this.css3DRenderer.domElement);
        
        // 创建控制器
        this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
        this.controls.enableDamping = true;
        this.controls.dampingFactor = 0.05;
        
        // 添加光源
        this.addLights();
        
        // 窗口大小调整
        window.addEventListener('resize', () => this.onWindowResize());
    }
    
    addLights() {
        // 环境光
        const ambientLight = new THREE.AmbientLight(0x404040, 0.4);
        this.scene.add(ambientLight);
        
        // 方向光
        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        directionalLight.position.set(10, 10, 5);
        directionalLight.castShadow = true;
        directionalLight.shadow.mapSize.width = 2048;
        directionalLight.shadow.mapSize.height = 2048;
        this.scene.add(directionalLight);
        
        // 点光源
        const pointLight = new THREE.PointLight(0xff6b6b, 0.5, 50);
        pointLight.position.set(-10, 10, -10);
        this.scene.add(pointLight);
    }
    
    createDemoObjects() {
        // 创建几何体数据 - 平行排列布局
        const objectsData = [
            { 
                geometry: new THREE.BoxGeometry(2, 2, 2),
                material: new THREE.MeshStandardMaterial({ color: 0x667eea }),
                position: [-8, 0, 0],
                label: '立方体\n蓝色几何体'
            },
            {
                geometry: new THREE.SphereGeometry(1.5, 32, 32),
                material: new THREE.MeshStandardMaterial({ color: 0xff6b6b }),
                position: [-4, 0, 0],
                label: '球体\n红色几何体'
            },
            {
                geometry: new THREE.ConeGeometry(1.5, 3, 8),
                material: new THREE.MeshStandardMaterial({ color: 0x00ff88 }),
                position: [0, 0, 0],
                label: '圆锥体\n绿色几何体'
            },
            {
                geometry: new THREE.CylinderGeometry(1, 1, 2, 16),
                material: new THREE.MeshStandardMaterial({ color: 0xffa500 }),
                position: [4, 0, 0],
                label: '圆柱体\n橙色几何体'
            },
            {
                geometry: new THREE.TorusGeometry(1, 0.4, 8, 16),
                material: new THREE.MeshStandardMaterial({ color: 0x9b59b6 }),
                position: [8, 0, 0],
                label: '环形体\n紫色几何体'
            }
        ];
        
        // 创建3D对象和对应标签
        objectsData.forEach((data, index) => {
            // 创建3D对象
            const mesh = new THREE.Mesh(data.geometry, data.material);
            mesh.position.set(...data.position);
            mesh.castShadow = true;
            mesh.receiveShadow = true;
            this.scene.add(mesh);
            this.demoObjects.push(mesh);
            
            // 创建CSS2D标签
            this.createCSS2DLabel(mesh, data.label, index);
            
            // 创建CSS3D标签
            this.createCSS3DLabel(mesh, data.label, index);
            
            // 创建Sprite标签
            this.createSpriteLabel(mesh, data.label, index);
            
            // 创建CSS3DSprite标签
            this.createCSS3DSpriteLabel(mesh, data.label, index);
        });
        
        // 初始显示CSS2D标签
        this.updateLabelVisibility();
    }
    
    createCSS2DLabel(mesh, text, index) {
        const labelDiv = document.createElement('div');
        labelDiv.className = 'css2d-label';
        labelDiv.innerHTML = text.replace('\\n', '<br>');
        labelDiv.style.pointerEvents = 'auto';
        
        // 添加点击事件
        labelDiv.addEventListener('click', () => {
            this.onLabelClick('css2d', index, mesh);
        });
        
        const css2dLabel = new THREE.CSS2DObject(labelDiv);
        css2dLabel.position.set(0, 1.8, 0); // 调整位置，使其在最下方
        mesh.add(css2dLabel);
        
        this.css2dLabels.push({
            object: css2dLabel,
            element: labelDiv,
            mesh: mesh,
            text: text
        });
    }
    
    createCSS3DLabel(mesh, text, index) {
        const labelDiv = document.createElement('div');
        labelDiv.className = 'css3d-label';
        labelDiv.innerHTML = text.replace('\\n', '<br>');
        labelDiv.style.pointerEvents = 'auto';
        
        // 添加点击事件
        labelDiv.addEventListener('click', () => {
            this.onLabelClick('css3d', index, mesh);
        });
        
        const css3dLabel = new THREE.CSS3DObject(labelDiv);
        css3dLabel.position.set(0, 3.2, 0); // 调整位置，使其在中间层
        css3dLabel.scale.set(0.01, 0.01, 0.01);
        mesh.add(css3dLabel);
        
        this.css3dLabels.push({
            object: css3dLabel,
            element: labelDiv,
            mesh: mesh,
            text: text
        });
    }
    
    createCSS3DSpriteLabel(mesh, text, index) {
        const labelDiv = document.createElement('div');
        labelDiv.className = 'css3dsprite-label';
        labelDiv.innerHTML = text.replace('\\n', '<br>');
        labelDiv.style.pointerEvents = 'auto';
        
        // 添加点击事件
        labelDiv.addEventListener('click', () => {
            this.onLabelClick('css3dsprite', index, mesh);
        });
        
        const css3dSpriteLabel = new THREE.CSS3DSprite(labelDiv);
        css3dSpriteLabel.position.set(0, 4.0, 0); // 调整位置，使其在顶层
        css3dSpriteLabel.scale.set(0.01, 0.01, 0.01);
        mesh.add(css3dSpriteLabel);
        
        this.css3dSpriteLabels.push({
            object: css3dSpriteLabel,
            element: labelDiv,
            mesh: mesh,
            text: text
        });
    }
    
    createSpriteLabel(mesh, text, index) {
        // 创建canvas纹理
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d');
        canvas.width = 256;
        canvas.height = 128;
        
        // 绘制背景 - 紫色渐变
        const gradient = context.createLinearGradient(0, 0, canvas.width, canvas.height);
        gradient.addColorStop(0, '#9C27B0');
        gradient.addColorStop(0.5, '#673AB7');
        gradient.addColorStop(1, '#3F51B5');
        context.fillStyle = gradient;
        context.fillRect(0, 0, canvas.width, canvas.height);
        
        // 绘制装饰性边框
        context.strokeStyle = '#E1BEE7';
        context.lineWidth = 6;
        context.strokeRect(3, 3, canvas.width - 6, canvas.height - 6);
        
        // 绘制内边框
        context.strokeStyle = '#ffffff';
        context.lineWidth = 2;
        context.strokeRect(8, 8, canvas.width - 16, canvas.height - 16);
        
        // 添加"SPRITE"标识
        context.fillStyle = '#FFD700';
        context.font = 'Bold 12px Arial';
        context.textAlign = 'right';
        context.textBaseline = 'top';
        context.fillText('SPRITE', canvas.width - 10, 10);
        
        // 绘制文字
        context.fillStyle = '#ffffff';
        context.font = 'Bold 22px Arial';
        context.textAlign = 'center';
        context.textBaseline = 'middle';
        
        // 添加文字阴影效果
        context.shadowColor = 'rgba(0, 0, 0, 0.8)';
        context.shadowBlur = 4;
        context.shadowOffsetX = 2;
        context.shadowOffsetY = 2;
        
        const lines = text.split('\\n');
        lines.forEach((line, i) => {
            const y = canvas.height / 2 + (i - (lines.length - 1) / 2) * 28;
            context.fillText(line, canvas.width / 2, y);
        });
        
        // 创建Sprite
        const texture = new THREE.CanvasTexture(canvas);
        const spriteMaterial = new THREE.SpriteMaterial({ 
            map: texture,
            transparent: true,
            alphaTest: 0.1
        });
        const sprite = new THREE.Sprite(spriteMaterial);
        sprite.position.set(0, 5.5, 0); // 调整位置，使其在最上方
        sprite.scale.set(3.5, 1.8, 1); // 稍微增大尺寸
        
        mesh.add(sprite);
        
        this.spriteLabels.push({
            object: sprite,
            mesh: mesh,
            text: text,
            canvas: canvas,
            context: context
        });
    }
    
    setupEventListeners() {
        // 标签类型切换
        const labelButtons = document.querySelectorAll('.label-btn');
        labelButtons.forEach(btn => {
            btn.addEventListener('click', (e) => {
                labelButtons.forEach(b => b.classList.remove('active'));
                e.target.classList.add('active');
                
                this.currentLabelType = e.target.dataset.type;
                this.updateLabelVisibility();
                this.updateCurrentLabelInfo();
            });
        });
        
        // 显示控制
        document.getElementById('show-all').addEventListener('change', (e) => {
            this.showAll = e.target.checked;
            this.updateLabelVisibility();
        });
        
        // 单独标签类型显示控制
        ['css2d', 'css3d', 'css3dsprite', 'sprite'].forEach(type => {
            document.getElementById(`show-${type}`).addEventListener('change', (e) => {
                this.labelVisibility[type] = e.target.checked;
                this.updateLabelVisibility();
            });
        });
        
        document.getElementById('auto-rotate').addEventListener('change', (e) => {
            this.autoRotate = e.target.checked;
        });
        
        document.getElementById('rotation-speed').addEventListener('input', (e) => {
            this.rotationSpeed = parseFloat(e.target.value);
            document.getElementById('rotation-speed-value').textContent = e.target.value;
        });
        
        // 相机控制
        document.getElementById('camera-distance').addEventListener('input', (e) => {
            const distance = parseFloat(e.target.value);
            const direction = this.camera.position.clone().normalize();
            this.camera.position.copy(direction.multiplyScalar(distance));
            document.getElementById('camera-distance-value').textContent = distance;
        });
        
        // 标签样式控制
        document.getElementById('label-size').addEventListener('input', (e) => {
            const size = e.target.value;
            this.updateLabelStyles('fontSize', size + 'px');
            document.getElementById('label-size-value').textContent = size + 'px';
        });
        
        document.getElementById('label-color').addEventListener('input', (e) => {
            this.updateLabelStyles('color', e.target.value);
        });
        
        document.getElementById('background-opacity').addEventListener('input', (e) => {
            const opacity = e.target.value;
            this.updateLabelStyles('opacity', opacity);
            document.getElementById('background-opacity-value').textContent = opacity;
        });
        
        // 初始化当前标签信息
        this.updateCurrentLabelInfo();
    }
    
    updateLabelVisibility() {
        if (this.showAll) {
            // 根据单独控制显示标签
            this.css2dLabels.forEach(label => {
                label.element.style.display = this.labelVisibility.css2d ? 'block' : 'none';
            });
            this.css3dLabels.forEach(label => {
                label.element.style.display = this.labelVisibility.css3d ? 'block' : 'none';
            });
            this.css3dSpriteLabels.forEach(label => {
                label.element.style.display = this.labelVisibility.css3dsprite ? 'block' : 'none';
            });
            this.spriteLabels.forEach(sprite => {
                sprite.object.visible = this.labelVisibility.sprite;
            });
        } else {
            // 只显示当前选中类型的标签（如果该类型被启用）
            this.css2dLabels.forEach(label => {
                label.element.style.display = (this.currentLabelType === 'css2d' && this.labelVisibility.css2d) ? 'block' : 'none';
            });
            this.css3dLabels.forEach(label => {
                label.element.style.display = (this.currentLabelType === 'css3d' && this.labelVisibility.css3d) ? 'block' : 'none';
            });
            this.css3dSpriteLabels.forEach(label => {
                label.element.style.display = (this.currentLabelType === 'css3dsprite' && this.labelVisibility.css3dsprite) ? 'block' : 'none';
            });
            this.spriteLabels.forEach(sprite => {
                sprite.object.visible = (this.currentLabelType === 'sprite' && this.labelVisibility.sprite);
            });
        }
        
        this.updateLabelCount();
    }
    
    updateLabelStyles(property, value) {
        // 更新CSS2D标签样式
        this.css2dLabels.forEach(label => {
            if (property === 'opacity') {
                label.element.style.backgroundColor = `rgba(0, 0, 0, ${value})`;
            } else {
                label.element.style[property] = value;
            }
        });
        
        // 更新CSS3D标签样式
        this.css3dLabels.forEach(label => {
            if (property === 'opacity') {
                label.element.style.backgroundColor = `rgba(102, 126, 234, ${value})`;
            } else {
                label.element.style[property] = value;
            }
        });
        
        // 更新CSS3DSprite标签样式
        this.css3dSpriteLabels.forEach(label => {
            if (property === 'opacity') {
                label.element.style.backgroundColor = `rgba(255, 165, 0, ${value})`;
            } else {
                label.element.style[property] = value;
            }
        });
        
        // Sprite标签需要重新绘制canvas
        if (property === 'fontSize' || property === 'color') {
            this.updateSpriteLabels();
        }
    }
    
    updateSpriteLabels() {
        this.spriteLabels.forEach(sprite => {
            const canvas = sprite.canvas;
            const context = sprite.context;
            
            // 清除canvas
            context.clearRect(0, 0, canvas.width, canvas.height);
            
            // 重新绘制
            const gradient = context.createLinearGradient(0, 0, canvas.width, canvas.height);
            gradient.addColorStop(0, '#667eea');
            gradient.addColorStop(1, '#764ba2');
            context.fillStyle = gradient;
            context.fillRect(0, 0, canvas.width, canvas.height);
            
            context.strokeStyle = '#ffffff';
            context.lineWidth = 4;
            context.strokeRect(2, 2, canvas.width - 4, canvas.height - 4);
            
            context.fillStyle = '#ffffff';
            context.font = 'Bold 20px Arial';
            context.textAlign = 'center';
            context.textBaseline = 'middle';
            
            const lines = sprite.text.split('\\n');
            lines.forEach((line, i) => {
                const y = canvas.height / 2 + (i - (lines.length - 1) / 2) * 25;
                context.fillText(line, canvas.width / 2, y);
            });
            
            sprite.object.material.map.needsUpdate = true;
        });
    }
    
    updateCurrentLabelInfo() {
        const info = this.labelTypes[this.currentLabelType];
        const detailsElement = document.getElementById('current-label-details');
        
        detailsElement.innerHTML = `
            <p><strong>类型:</strong> ${info.name}</p>
            <p><strong>描述:</strong> ${info.description}</p>
        `;
        
        // 更新标签特性
        this.updateLabelFeatures(info);
        
        // 更新使用场景建议
        this.updateUsageScenarios(info);
        
        // 更新代码使用案例
        this.updateCodeExamples(info);
    }
    
    updateLabelFeatures(info) {
        const featuresElement = document.getElementById('current-features');
        const featureTagsHtml = info.features.map(feature => 
            `<div class="feature-tag">${feature}</div>`
        ).join('');
        
        const colorMap = {
            'css2d': '#4CAF50',
            'css3d': '#2196F3', 
            'css3dsprite': '#FF9800',
            'sprite': '#9C27B0'
        };
        
        featuresElement.innerHTML = `
            <div class="feature-list">
                ${featureTagsHtml}
            </div>
            <div class="feature-description">
                <p>${info.description}</p>
            </div>
        `;
        
        // 更新特性标签颜色
        const featureTags = featuresElement.querySelectorAll('.feature-tag');
        featureTags.forEach(tag => {
            tag.style.background = `linear-gradient(135deg, ${colorMap[this.currentLabelType]} 0%, ${colorMap[this.currentLabelType]}CC 100%)`;
        });
    }
    
    updateUsageScenarios(info) {
        const usageElement = document.getElementById('usage-content');
        
        const recommendedHtml = info.useCases.map(useCase => 
            `<li>${useCase}</li>`
        ).join('');
        
        const notRecommendedHtml = info.limitations.map(limitation => 
            `<li>${limitation}</li>`
        ).join('');
        
        usageElement.innerHTML = `
            <div class="scenario-item">
                <h5>✅ 推荐场景</h5>
                <ul>
                    ${recommendedHtml}
                </ul>
            </div>
            <div class="scenario-item">
                <h5>❌ 注意事项</h5>
                <ul>
                    ${notRecommendedHtml}
                </ul>
            </div>
        `;
    }
    
    updateCodeExamples(info) {
        const codeElement = document.getElementById('code-content');
        
        const codeExamples = this.getCodeExamples(this.currentLabelType);
        
        codeElement.innerHTML = codeExamples.map(example => `
            <div class="code-section">
                <h5>${example.title}</h5>
                <pre><code>${example.code}</code></pre>
            </div>
        `).join('');
    }
    
    getCodeExamples(type) {
        const examples = {
            css2d: [
                {
                    title: '基础创建',
                    code: `// 创建CSS2D标签
const labelDiv = document.createElement('div');
labelDiv.className = 'css2d-label';
labelDiv.textContent = '标签文本';

const label = new THREE.CSS2DObject(labelDiv);
label.position.set(0, 2, 0);
mesh.add(label);`
                },
                {
                    title: '样式设置',
                    code: `// CSS样式
.css2d-label {
  background: rgba(0,0,0,0.8);
  color: white;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 14px;
}`
                },
                {
                    title: '渲染器设置',
                    code: `// 创建CSS2D渲染器
const css2dRenderer = new THREE.CSS2DRenderer();
css2dRenderer.setSize(width, height);
css2dRenderer.domElement.style.position = 'absolute';
css2dRenderer.domElement.style.top = '0';
container.appendChild(css2dRenderer.domElement);`
                }
            ],
            css3d: [
                {
                    title: '基础创建',
                    code: `// 创建CSS3D标签
const labelDiv = document.createElement('div');
labelDiv.className = 'css3d-label';
labelDiv.textContent = '3D标签文本';

const label = new THREE.CSS3DObject(labelDiv);
label.position.set(0, 2, 0);
label.scale.set(0.01, 0.01, 0.01);
mesh.add(label);`
                },
                {
                    title: '3D变换',
                    code: `// 3D旋转和缩放
label.rotation.x = Math.PI / 4;
label.rotation.y = Math.PI / 6;
label.scale.set(0.02, 0.02, 0.02);

// 动画变换
function animate() {
  label.rotation.y += 0.01;
}`
                },
                {
                    title: '渲染器设置',
                    code: `// 创建CSS3D渲染器
const css3dRenderer = new THREE.CSS3DRenderer();
css3dRenderer.setSize(width, height);
css3dRenderer.domElement.style.position = 'absolute';
css3dRenderer.domElement.style.pointerEvents = 'none';
container.appendChild(css3dRenderer.domElement);`
                }
            ],
            css3dsprite: [
                {
                    title: '基础创建',
                    code: `// 创建CSS3DSprite标签
const labelDiv = document.createElement('div');
labelDiv.className = 'css3dsprite-label';
labelDiv.textContent = 'Sprite标签文本';

const label = new THREE.CSS3DSprite(labelDiv);
label.position.set(0, 2, 0);
label.scale.set(0.01, 0.01, 0.01);
mesh.add(label);`
                },
                {
                    title: '精灵特性',
                    code: `// 始终面向相机
// CSS3DSprite会自动面向相机
// 无需手动设置旋转

// 缩放控制
label.scale.setScalar(0.015);

// 位置偏移
label.position.y = 3.0;`
                },
                {
                    title: '样式设置',
                    code: `// CSS样式
.css3dsprite-label {
  background: linear-gradient(135deg, #FF9800, #F57C00);
  color: white;
  padding: 12px 18px;
  border-radius: 12px;
  border: 2px solid #FFB74D;
}`
                }
            ],
            sprite: [
                {
                    title: '基础创建',
                    code: `// 创建Sprite标签
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = 256;
canvas.height = 128;

// 绘制文本
context.fillStyle = '#9C27B0';
context.fillRect(0, 0, canvas.width, canvas.height);
context.fillStyle = 'white';
context.font = 'bold 24px Arial';
context.textAlign = 'center';
context.fillText('Sprite标签', canvas.width/2, canvas.height/2);`
                },
                {
                    title: '纹理和材质',
                    code: `// 创建纹理和材质
const texture = new THREE.CanvasTexture(canvas);
const material = new THREE.SpriteMaterial({ map: texture });
const sprite = new THREE.Sprite(material);

// 设置位置和缩放
sprite.position.set(0, 2, 0);
sprite.scale.set(2, 1, 1);
mesh.add(sprite);`
                },
                {
                    title: '动态更新',
                    code: `// 更新Sprite内容
function updateSprite(text, color) {
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.fillStyle = color;
  context.fillRect(0, 0, canvas.width, canvas.height);
  context.fillStyle = 'white';
  context.fillText(text, canvas.width/2, canvas.height/2);
  texture.needsUpdate = true;
}`
                }
            ]
        };
        
        return examples[type] || [];
    }
    
    onLabelClick(type, index, mesh) {
        console.log(`点击了 ${type} 标签，对象索引: ${index}`);
        
        // 更新属性显示
        this.updateLabelProperties(mesh, type);
        
        // 高亮对象
        this.highlightObject(mesh);
    }
    
    updateLabelProperties(mesh, type) {
        const position = mesh.position;
        const scale = mesh.scale;
        
        document.getElementById('label-position').textContent = 
            `x: ${position.x.toFixed(1)}, y: ${position.y.toFixed(1)}, z: ${position.z.toFixed(1)}`;
        
        document.getElementById('label-size-display').textContent = 
            document.getElementById('label-size').value + 'px';
        
        document.getElementById('label-opacity-display').textContent = 
            document.getElementById('background-opacity').value;
        
        document.getElementById('label-visibility').textContent = 
            this.isLabelVisible(type) ? '可见' : '隐藏';
    }
    
    isLabelVisible(type) {
        if (this.showAll) return true;
        return this.currentLabelType === type;
    }
    
    highlightObject(mesh) {
        // 重置所有对象材质
        this.demoObjects.forEach(obj => {
            obj.material.emissive.setHex(0x000000);
        });
        
        // 高亮选中对象
        mesh.material.emissive.setHex(0x444444);
        
        // 2秒后恢复
        setTimeout(() => {
            mesh.material.emissive.setHex(0x000000);
        }, 2000);
    }
    
    updateLabelCount() {
        let visibleCount = 0;
        
        if (this.showAll) {
            // 计算所有启用类型的标签数量
            if (this.labelVisibility.css2d) visibleCount += this.css2dLabels.length;
            if (this.labelVisibility.css3d) visibleCount += this.css3dLabels.length;
            if (this.labelVisibility.css3dsprite) visibleCount += this.css3dSpriteLabels.length;
            if (this.labelVisibility.sprite) visibleCount += this.spriteLabels.length;
        } else {
            // 只计算当前选中且启用的类型
            switch (this.currentLabelType) {
                case 'css2d':
                    visibleCount = this.labelVisibility.css2d ? this.css2dLabels.length : 0;
                    break;
                case 'css3d':
                    visibleCount = this.labelVisibility.css3d ? this.css3dLabels.length : 0;
                    break;
                case 'css3dsprite':
                    visibleCount = this.labelVisibility.css3dsprite ? this.css3dSpriteLabels.length : 0;
                    break;
                case 'sprite':
                    visibleCount = this.labelVisibility.sprite ? this.spriteLabels.length : 0;
                    break;
            }
        }
        
        document.getElementById('label-count').textContent = visibleCount;
    }
    
    updatePerformanceMonitor() {
        const now = performance.now();
        this.performanceMonitor.frameCount++;
        
        if (now >= this.performanceMonitor.lastTime + 1000) {
            this.performanceMonitor.fps = Math.round(
                (this.performanceMonitor.frameCount * 1000) / (now - this.performanceMonitor.lastTime)
            );
            this.performanceMonitor.frameCount = 0;
            this.performanceMonitor.lastTime = now;
            
            document.getElementById('fps').textContent = this.performanceMonitor.fps;
        }
    }
    
    onWindowResize() {
        const container = document.getElementById('canvas').parentElement;
        const width = container.clientWidth;
        const height = container.clientHeight;
        
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix();
        
        this.renderer.setSize(width, height);
        this.css2DRenderer.setSize(width, height);
        this.css3DRenderer.setSize(width, height);
    }
    
    animate() {
        this.animationId = requestAnimationFrame(() => this.animate());
        
        const renderStart = performance.now();
        
        // 自动旋转
        if (this.autoRotate) {
            this.demoObjects.forEach(mesh => {
                mesh.rotation.y += this.rotationSpeed;
                mesh.rotation.x += this.rotationSpeed * 0.5;
            });
        }
        
        // 更新控制器
        this.controls.update();
        
        // 渲染
        this.renderer.render(this.scene, this.camera);
        this.css2DRenderer.render(this.scene, this.camera);
        this.css3DRenderer.render(this.scene, this.camera);
        
        // 性能监控
        this.performanceMonitor.renderTime = performance.now() - renderStart;
        document.getElementById('render-time').textContent = 
            this.performanceMonitor.renderTime.toFixed(2) + 'ms';
        
        this.updatePerformanceMonitor();
    }
    
    destroy() {
        if (this.animationId) {
            cancelAnimationFrame(this.animationId);
        }
        
        // 清理资源
        this.scene.clear();
        this.renderer.dispose();
        
        // 移除DOM元素
        if (this.css2DRenderer.domElement.parentNode) {
            this.css2DRenderer.domElement.parentNode.removeChild(this.css2DRenderer.domElement);
        }
        if (this.css3DRenderer.domElement.parentNode) {
            this.css3DRenderer.domElement.parentNode.removeChild(this.css3DRenderer.domElement);
        }
    }
}

// 初始化应用
let demo;
window.addEventListener('DOMContentLoaded', () => {
    demo = new LabelDemo();
});

// 页面卸载时清理资源
window.addEventListener('beforeunload', () => {
    if (demo) {
        demo.destroy();
    }
});